﻿// main.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//


// KCP 算法1
// 输入57600, 输出2304, 模分解 (15*16*16*15) * (8*6*6*8)
// C_A = 4, C_B = 4


#include <time.h>
#include <math.h>
#include "GlobalValues.h"
#include "Uncompressed.h"
#include "NormalAlgo.h"
#include "OpenCLKernel.h"


const int g_n_dimInput = 57600;
const int g_n_dimOutput = 2304;
const int g_nl_modesInput[4] = { 15, 16, 16, 15 };
const int g_nl_modesOutput[4] = { 8, 6, 6, 8 };
const int g_n_rankA = 4;
const int g_n_rankB = 4;

float* g_pUncompW = nullptr;
float* g_pInput = nullptr;
float* g_pOutputCPU = nullptr;
float* g_pOutputGPU = nullptr;


void InitMemories()
{
	printf("Initialize the Uncompressed Weight...\n");
    if (g_pUncompW == nullptr)
    {
        g_pUncompW = new float[g_n_dimInput * g_n_dimOutput];
        srand(time(0));
        for (int i = 0; i < g_n_dimInput * g_n_dimOutput; g_pUncompW[i] = rand() & 0xF, i++);
    }

	printf("Initialize the Input...\n");
    if (g_pInput == nullptr)
    {
        g_pInput = new float[g_n_dimInput];
        srand(time(0));
        for (int i = 0; i < g_n_dimInput; g_pInput[i] = rand() & 0xF, i++);
    }

	printf("Initialize the Output...\n");
    if (g_pOutputCPU == nullptr)
    {
        g_pOutputCPU = new float[g_n_dimOutput];
        memset(g_pOutputCPU, 0, sizeof(float) * g_n_dimOutput);
    }
    if (g_pOutputGPU == nullptr)
    {
        g_pOutputGPU = new float[g_n_dimOutput];
        memset(g_pOutputGPU, 0, sizeof(float) * g_n_dimOutput);
    }
}


void DelMemories()
{
    if (g_pUncompW != nullptr)
    {
        delete[] g_pUncompW;
        g_pUncompW = nullptr;
    }
    if (g_pInput != nullptr)
    {
        delete[] g_pInput;
        g_pInput = nullptr;
    }
    if (g_pOutputCPU != nullptr)
    {
        delete[] g_pOutputCPU;
        g_pOutputCPU = nullptr;
    }
    if (g_pOutputGPU != nullptr)
    {
        delete[] g_pOutputGPU;
        g_pOutputGPU = nullptr;
    }
}


void ResultCompare()
{
    int rslt = memcmp(g_pOutputCPU, g_pOutputGPU, sizeof(float) * g_n_dimOutput);
    if (rslt == 0)
        printf("   The result is correct.\n");
    else
        printf("   The result is NOT correct: the first value is %f / %f (CPU / GPU).\n", g_pOutputCPU[0], g_pOutputGPU[0]);
}


int main()
{
    InitMemories();

    OpenCLKernel* m_pOCL = new OpenCLKernel;
    if (0 != m_pOCL->OpenCLInitialize())
    {
        delete m_pOCL;
        m_pOCL = nullptr;
        return EXIT_FAILURE;
    }


    printf("Start to run...\n");
    long t_cpu, t_gpu;

    // 非压缩的原始计算
    t_cpu = UncompressedAlgorithmProcess();
    t_gpu = UncompressedAlgorithmProcess_OCL(m_pOCL);
    printf("1. The uncompressed form runs: %d / %d ms (CPU / GPU).\n", t_cpu, t_gpu);
    ResultCompare();

    DelMemories();

    return 0;   
}
